package net.goutalk.glcs.module.system.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.toolkit.MPJWrappers;
import net.goutalk.glcs.common.constant.GlobalConstant;
import net.goutalk.glcs.common.enums.AuthorizeType;
import net.goutalk.glcs.common.enums.EnabledMark;
import net.goutalk.glcs.common.utils.VoToColumnUtil;
import net.goutalk.glcs.module.organization.entity.UserRoleRelation;
import net.goutalk.glcs.module.organization.mapper.UserRoleRelationMapper;
import net.goutalk.glcs.module.system.dto.MenuTreeDto;
import net.goutalk.glcs.module.system.entity.Authorize;
import net.goutalk.glcs.module.system.entity.Menu;
import net.goutalk.glcs.module.system.entity.Subsystem;
import net.goutalk.glcs.module.system.mapper.AuthorizeMapper;
import net.goutalk.glcs.module.system.mapper.MenuMapper;
import net.goutalk.glcs.module.system.service.IMenuService;
import net.goutalk.glcs.module.system.vo.MenuTreeVo;
import net.goutalk.glcs.module.system.vo.MenuVo;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户 服务实现类
 * </p>
 *
 * @author tanyujie
 * @since 2022-03-16
 */
@Service
@AllArgsConstructor
public class MenuServiceImpl extends MPJBaseServiceImpl<MenuMapper, Menu> implements IMenuService {

    private final UserRoleRelationMapper userRoleRelationMapper;

    private final AuthorizeMapper authorizeMapper;

    @Override
    public List<MenuVo> getAuthMenuList(MenuTreeDto dto) {
        List<UserRoleRelation> relations = userRoleRelationMapper.selectList(Wrappers.lambdaQuery(UserRoleRelation.class)
                .select(UserRoleRelation::getRoleId)
                .eq(UserRoleRelation::getUserId, StpUtil.getLoginIdAsLong()));
        if (CollectionUtils.isEmpty(relations)) {
            return new ArrayList<>();
        }
        List<Long> roleIds = relations.stream().map(UserRoleRelation::getRoleId).collect(Collectors.toList());
        List<Long> authMenuIdList = null;
        // 非超级管理员权限过滤
        if (!roleIds.contains(GlobalConstant.SUPER_ADMIN_ROLE_ID)) {
            List<Authorize> authorizeList = authorizeMapper.selectList(Wrappers.<Authorize>lambdaQuery()
                    .eq(Authorize::getAuthorizeType, AuthorizeType.MENU.getCode())
                    .in(Authorize::getRoleId, roleIds));
            if (CollectionUtils.isEmpty(authorizeList)) {
                return new ArrayList<>();
            }
            authMenuIdList = authorizeList.stream().map(Authorize::getObjectId).collect(Collectors.toList());
        }

        return this.selectJoinList(MenuVo.class,
                MPJWrappers.<Menu>lambdaJoin()
                    .like(StrUtil.isNotBlank(dto.getTitle()), Menu::getTitle, dto.getTitle())
                    .like(StrUtil.isNotBlank(dto.getCode()), Menu::getCode, dto.getCode())
                    .like(StrUtil.isNotBlank(dto.getName()), Menu::getName, dto.getName())
    //                .like(ObjectUtil.isNotEmpty(dto.getEnabledMark()), Menu::getEnabledMark, dto.getEnabledMark())
                    .in(CollectionUtils.isNotEmpty(authMenuIdList), Menu::getId, authMenuIdList)
                    .select(Menu::getId)
                    .selectAs(Subsystem::getName, MenuVo::getSystemName)
                    .select(Menu.class, x -> VoToColumnUtil.fieldsToColumns(MenuTreeVo.class).contains(x.getProperty()))
                    .leftJoin(Subsystem.class, Subsystem::getId, Menu::getSystemId)
                    .eq(Menu::getEnabledMark, EnabledMark.ENABLED.getCode())
                    .orderByAsc(Menu::getSortCode));
    }
}
